Skip to content

fix(start): align request handler types with registered server context#7428

Open
SeanCassiere wants to merge 11 commits into
mainfrom
refactor/adjust-types-for-start-register-declaration
Open

fix(start): align request handler types with registered server context#7428
SeanCassiere wants to merge 11 commits into
mainfrom
refactor/adjust-types-for-start-register-declaration

Conversation

@SeanCassiere
Copy link
Copy Markdown
Member

@SeanCassiere SeanCassiere commented May 17, 2026

In reference to #7399

Summary by CodeRabbit

  • Bug Fixes

    • Aligned request handler types with registered server context in React Start, Solid Start, and Vue Start frameworks for improved type safety and consistency.
  • Documentation

    • Updated server entry-point documentation to reflect correct module augmentation patterns for server request context typing.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR aligns request handler types across the start framework packages by updating where the Register type is imported. React, Solid, and Vue start packages now source Register from their respective start packages instead of router packages. E2E tests validate the pattern with module augmentation and context passing, and documentation is updated to reflect the correct augmentation targets.

Changes

Request Handler Type Alignment

Layer / File(s) Summary
Framework package Register imports
packages/react-start/src/default-entry/server.ts, packages/solid-start/src/default-entry/server.ts, packages/vue-start/src/default-entry/server.ts
React, Solid, and Vue start packages import Register from their respective start packages instead of router packages, aligning the ServerEntry.fetch handler signature with the start package's type registry.
E2E test context validation and documentation
e2e/react-start/basic/src/server.ts, e2e/solid-start/basic/src/server.ts, e2e/vue-start/basic/src/server.ts, docs/start/framework/react/guide/server-entry-point.md, docs/start/framework/solid/guide/server-entry-point.md
E2E servers demonstrate module augmentation of Register.server.requestContext with typed foo: string fields and pass context objects through handler.fetch calls. React and Solid documentation examples are updated to show augmenting Register from start packages, with Solid's alias mapping simplified.
Release documentation
.changeset/thick-sloths-write.md
Changeset entry documents patch releases across all start packages with a fix(start) note about aligning request handler types with registered server context.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • TanStack/router#7399: Addresses the same type alignment for RequestHandler and Register.requestContext across the start packages ecosystem.

Possibly related PRs

  • TanStack/router#7427: Modifies the same React server-entry-point documentation example, updating the declare module target for request-context augmentation.

Poem

🐰 The types now flow from start instead of route,
Where Register finds its home so true,
E2E hops and docs align in sync,
Context passes through with types that fit just right,
A fluffy fix for frameworks taking flight! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title directly and accurately describes the main change: aligning request handler types with the registered server context by adjusting type imports across framework packages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/adjust-types-for-start-register-declaration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented May 17, 2026

View your CI Pipeline Execution ↗ for commit d8feafb

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 1m 13s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-31 21:07:43 UTC

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 17, 2026

🚀 Changeset Version Preview

3 package(s) bumped directly, 0 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/react-start 1.168.18 → 1.168.19 Changeset
@tanstack/solid-start 1.168.18 → 1.168.19 Changeset
@tanstack/vue-start 1.168.17 → 1.168.18 Changeset

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 17, 2026

Bundle Size Benchmarks

  • Commit: af67467e0e7a
  • Measured at: 2026-05-31T21:07:32.364Z
  • Baseline source: history:9a6c12596ff6
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Initial gzip Raw Brotli Trend
react-router.minimal 87.25 KiB 0 B (0.00%) 87.12 KiB 273.94 KiB 75.84 KiB ███████▁▁▁▁
react-router.full 90.69 KiB 0 B (0.00%) 90.55 KiB 285.30 KiB 78.83 KiB ███████▁▁▁▁
solid-router.minimal 35.47 KiB 0 B (0.00%) 35.35 KiB 106.24 KiB 32.00 KiB ███████▁▁▁▁
solid-router.full 40.18 KiB 0 B (0.00%) 40.05 KiB 120.43 KiB 36.18 KiB ███████▁▁▁▁
vue-router.minimal 52.97 KiB 0 B (0.00%) 52.84 KiB 150.26 KiB 47.66 KiB ███████▁▁▁▁
vue-router.full 58.60 KiB 0 B (0.00%) 58.47 KiB 167.99 KiB 52.51 KiB ███████▁▁▁▁
react-start.minimal 101.88 KiB 0 B (0.00%) 101.74 KiB 322.26 KiB 88.15 KiB ███████▁▁▁▁
react-start.deferred-hydration 102.61 KiB 0 B (0.00%) 101.76 KiB 323.63 KiB 88.82 KiB ███████▁▁▁▁
react-start.full 105.26 KiB 0 B (0.00%) 105.12 KiB 332.57 KiB 91.09 KiB ███████▁▁▁▁
react-start.rsbuild.minimal 99.58 KiB 0 B (0.00%) 99.41 KiB 316.74 KiB 85.74 KiB ███████▁▁▄▄
react-start.rsbuild.full 102.85 KiB 0 B (0.00%) 102.68 KiB 327.13 KiB 88.45 KiB ███████▁▁▄▄
solid-start.minimal 49.58 KiB 0 B (0.00%) 49.45 KiB 152.31 KiB 43.78 KiB ███████▁▁▁▁
solid-start.deferred-hydration 52.84 KiB 0 B (0.00%) 49.51 KiB 160.35 KiB 46.76 KiB ███████▁▁▁▁
solid-start.full 55.37 KiB 0 B (0.00%) 55.24 KiB 169.24 KiB 48.76 KiB ███████▁▁▁▁

Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better.

@SeanCassiere SeanCassiere changed the title refactor: start should export and use its own Register interface refactor(start): export and use its own Register interface May 17, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 17, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@7428

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@7428

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@7428

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@7428

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@7428

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@7428

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@7428

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@7428

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@7428

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@7428

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@7428

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@7428

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@7428

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@7428

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@7428

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@7428

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@7428

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@7428

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@7428

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@7428

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@7428

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@7428

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@7428

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@7428

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@7428

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@7428

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@7428

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@7428

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@7428

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@7428

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@7428

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@7428

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@7428

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@7428

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@7428

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@7428

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@7428

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@7428

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@7428

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@7428

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@7428

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@7428

commit: bd4dd3f

@SeanCassiere SeanCassiere marked this pull request as ready for review May 17, 2026 23:29
@SeanCassiere SeanCassiere marked this pull request as draft May 17, 2026 23:34
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 17, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing refactor/adjust-types-for-start-register-declaration (bd4dd3f) with main (9a6c125)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@SeanCassiere SeanCassiere force-pushed the refactor/adjust-types-for-start-register-declaration branch from 89310e0 to d6b0635 Compare May 21, 2026 23:43
@SeanCassiere SeanCassiere changed the title refactor(start): export and use its own Register interface fix(start): align request handler types with registered server context May 21, 2026
@SeanCassiere SeanCassiere marked this pull request as ready for review May 21, 2026 23:44
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/start-server-core/src/createStartHandler.ts`:
- Around line 325-327: startRequestResolver is declared as
RequestHandler<Register> with requestOpts?: RequestOptions<Register>, but the
code later casts it to RequestHandler<TRegister>, which hides
RequestOptions<TRegister> constraints such as required server.requestContext;
instead make startRequestResolver generic over TRegister (or accept
RequestOptions<TRegister>) within createStartHandler so its signature matches
RequestHandler<TRegister> without casting—update the function/type parameters
(startRequestResolver, RequestOptions, RequestHandler, createStartHandler,
TRegister, Register) so the resolver uses the generic TRegister request option
types (including requestContext when present) and remove the unsafe cast.

In `@packages/start-server-core/src/request-response.ts`:
- Around line 125-128: The wrapper currently declares requestOpts?: any which
bypasses the RequestHandler<TRegister> contract and then re-establishes types
via a cast; change the wrapper signature to accept the strongly-typed options
instead of any so the wrapper itself matches RequestHandler<TRegister> (i.e.,
replace requestOpts?: any with the correct generic opts type for TRegister and
adjust the wrapper return type to Promise<Response> | Response as needed),
remove the subsequent as RequestHandler<TRegister> cast, and ensure the internal
call sites use the typed opts variable (references: the wrapper function taking
(request: Request, requestOpts), the RequestHandler<TRegister> type and the
TRegister generic).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7286b653-e8ba-4a37-ae1f-5478603a1e1f

📥 Commits

Reviewing files that changed from the base of the PR and between 9d0ba3e and d6b0635.

📒 Files selected for processing (8)
  • .changeset/thick-sloths-write.md
  • packages/react-start/src/default-entry/server.ts
  • packages/solid-start/src/default-entry/server.ts
  • packages/start-server-core/src/createStartHandler.ts
  • packages/start-server-core/src/index.tsx
  • packages/start-server-core/src/request-handler.ts
  • packages/start-server-core/src/request-response.ts
  • packages/vue-start/src/default-entry/server.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/start-server-core/src/index.tsx
  • .changeset/thick-sloths-write.md

Comment thread packages/start-server-core/src/createStartHandler.ts Outdated
Comment on lines +125 to +128
return ((
request: Request,
requestOpts?: any,
): Promise<Response> | Response => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify unsafe typing in wrapper signatures
rg -n -C2 'requestOpts\?: any|as RequestHandler<|RequestHandlerParameters<' packages/start-server-core/src/request-response.ts

Repository: TanStack/router

Length of output: 342


requestOpts?: any bypasses the handler type guarantees (and is masked by a cast).

In packages/start-server-core/src/request-response.ts, the wrapper takes requestOpts?: any (line 127) and then relies on as RequestHandler<TRegister> (line 146) to restore typing. This defeats strict type safety for the TRegister-specific opts contract. Replace any with the correct typed parameters for TRegister and remove/avoid the cast by aligning the wrapper’s parameter/return types with RequestHandler<TRegister] directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/start-server-core/src/request-response.ts` around lines 125 - 128,
The wrapper currently declares requestOpts?: any which bypasses the
RequestHandler<TRegister> contract and then re-establishes types via a cast;
change the wrapper signature to accept the strongly-typed options instead of any
so the wrapper itself matches RequestHandler<TRegister> (i.e., replace
requestOpts?: any with the correct generic opts type for TRegister and adjust
the wrapper return type to Promise<Response> | Response as needed), remove the
subsequent as RequestHandler<TRegister> cast, and ensure the internal call sites
use the typed opts variable (references: the wrapper function taking (request:
Request, requestOpts), the RequestHandler<TRegister> type and the TRegister
generic).

nx-cloud[bot]

This comment was marked as outdated.

…t-start

Add a Start-owned Register interface that extends router-core's
Register, then export and consume it from `start-client-core`.

This lets declarations against `@tanstack/react-start`, including
`server.requestContext`, flow into Start-specific type consumers instead
of requiring users to augment `@tanstack/router-core` or
`@tanstack/react-router` directly.

Router-core Register augmentations remain compatible because Start's
Register extends the core Register.
Import Register from `@tanstack/start-client-core` in
`createStartHandler` instead of `@tanstack/router-core`.

This makes the server handler default to Start's augmentation surface,
allowing `@tanstack/react-start` Register declarations such as
`server.requestContext` to flow into RequestHandler typing.
…e the request context (#7427)

This reverts commit 2506478 since these
changes now can infer the types off of Start's Register interface
Use the shared router-core Register for Start request handler types while preserving the documented custom server entry shape.

Request options now derive required context from Register.server.requestContext, but framework ServerEntry wrappers still accept the universal fetch handler form with optional request options.
@SeanCassiere SeanCassiere force-pushed the refactor/adjust-types-for-start-register-declaration branch from 73a9c6d to bfdf4bb Compare May 31, 2026 20:32
nx-cloud[bot]

This comment was marked as outdated.

SeanCassiere and others added 2 commits June 1, 2026 08:52
… import

Fixing the augmented `server.requestContext` typing only needs the
default-entry `ServerEntry` to import `Register` from the framework start
package (the module users augment), not the router package. Module
augmentation flows only when the consuming type imports `Register` from
the same specifier and that module is in the type graph.

Revert the broader, unnecessary churn back to main:
- start-server-core: request-handler, createStartHandler, request-response
  signatures (RequestHandler/RequestOptions/RequestHandlerParameters)
- e2e react-start import-protection test
- changeset: drop start-client-core/start-server-core (now unchanged)

Verified against built packages: e2e react/solid/vue basic `tsc --noEmit`
pass; wrong context value and missing required context are rejected;
start-client-core/start-server-core test:types pass.
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a flaky task in your failed CI:

🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.

Nx Cloud View detailed reasoning in Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant